package xyz.hubery.util;

import com.alicp.jetcache.Cache;
import com.alicp.jetcache.anno.CacheType;
import com.alicp.jetcache.anno.CreateCache;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import xyz.hubery.disruptor.OrderEventHandler;
import xyz.hubery.domain.DepthItemVo;
import xyz.hubery.model.DepthSnapshot;
import xyz.hubery.model.TradePlate;

import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 盘口数据缓存管理类
 */
@Slf4j
@Component
public class DepthCacheManager {

    // 创建缓存实例 - 多级缓存（本地内存 + Redis）
    @CreateCache(name = "market.depth.", expire = 2, timeUnit = TimeUnit.MINUTES,
            localLimit = 100, localExpire = 2,
            cacheType = CacheType.BOTH)  // 本地 + 远程两级缓存
    private Cache<String, DepthSnapshot> depthCache;
    // 符号到事件处理器的快速映射
    private final ConcurrentHashMap<String, OrderEventHandler> handlerMap = new ConcurrentHashMap<>();

    /**
     * 撮合线程调用：更新缓存
     */
    public void updateDepthSnapshot(String symbol, TradePlate buyPlate, TradePlate sellPlate) {
        DepthSnapshot snapshot = new DepthSnapshot(
                copyDepthItems(buyPlate.getItems()),  // 创建快照，避免后续修改
                copyDepthItems(sellPlate.getItems()),
                System.currentTimeMillis()
        );
        // JetCache 自动处理多级缓存
        depthCache.put(symbol, snapshot);
    }

    /**
     * 接口线程调用：查询缓存
     */
    public Map<String, List<DepthItemVo>> getSymbolDepth(String symbol) {
        try {
            DepthSnapshot snapshot = depthCache.get(symbol);
            if (snapshot != null) {
                Map<String, List<DepthItemVo>> result = new HashMap<>(2);
                result.put("bids", snapshot.getBids());
                result.put("asks", snapshot.getAsks());
                return result;
            }
        }catch (Exception e) {
            // 降级处理
            log.warn("Get depth cache failed: {}", e.getMessage());
        }
        return Collections.emptyMap();
    }

    /**
     * 注册事件处理器
     */
    public void registerHandler(OrderEventHandler handler) {
        handlerMap.put(handler.getSymbol(), handler);
    }

    /**
     * 获取事件处理器（如果需要直接访问）
     */
    public OrderEventHandler getHandler(String symbol) {
        return handlerMap.get(symbol);
    }


    /**
     * 深度拷贝，防止返回源对象引用，其他线程修改导致值变化
     */
    private List<DepthItemVo> copyDepthItems(List<DepthItemVo> original) {
        if (original == null) {
            return Collections.emptyList();
        }

        return original.stream()
                .map(this::copyDepthItem)
                .collect(Collectors.toList());
    }

    /**
     * 拷贝单个DepthItemVo
     */
    private DepthItemVo copyDepthItem(DepthItemVo original) {
        if (original == null) {
            return null;
        }

        return DepthItemVo.builder()
                .price(original.getPrice())
                .volume(original.getVolume())
                .build();
    }


}
